<?php

namespace app\api\controller;

use app\api\model\MemberModel;
use library\logic\Query;
use think\Exception;
use think\exception\HttpResponseException;
use think\exception\PDOException;
use think\facade\Cache;
use think\Request;

class ApiController {

    protected $request;
    protected $_userInfo;
    protected $_token;
    /**
     * @var array 前置操作方法列表
     */
    protected $beforeActionList = [];

    public function __construct(Request $request = null) {
        $this->request = request();
        // 控制器初始化
        $this->_initialize();
        // 前置操作方法
        if ($this->beforeActionList) {
            foreach ($this->beforeActionList as $method => $options) {
                is_numeric($method) ?
                    $this->beforeAction($options) :
                    $this->beforeAction($method, $options);
            }
        }

    }

    /**
     * 初始化操作
     * @access protected
     */
    protected function _initialize() {
    }

    /**
     * 前置操作
     * @access protected
     * @param string $method 前置操作方法名
     * @param array $options 调用参数 ['only'=>[...]] 或者 ['except'=>[...]]
     * @return void
     */
    protected function beforeAction($method, $options = []) {
        if (isset($options['only'])) {
            if (is_string($options['only'])) {
                $options['only'] = explode(',', $options['only']);
            }
            if (!in_array($this->request->action(), $options['only'])) {
                return;
            }
        } elseif (isset($options['except'])) {
            if (is_string($options['except'])) {
                $options['except'] = explode(',', $options['except']);
            }

            if (in_array($this->request->action(), $options['except'])) {
                return;
            }
        }
        call_user_func([$this, $method]);
    }

    /**
     * 返回失败的操作
     * @param mixed $info 消息内容
     * @param array $data 返回数据
     * @param integer $code 返回代码
     */
    public function error($info, $data = [], $code = 0) {
        $result = ['code' => $code, 'info' => $info, 'data' => $data];
        throw new HttpResponseException(json($result));
    }

    /**
     * 返回成功的操作
     * @param mixed $info 消息内容
     * @param array $data 返回数据
     * @param integer $code 返回代码
     */
    public function success($info, $data = [], $code = 1) {
        $result = ['code' => $code, 'info' => $info, 'data' => $data];
        throw new HttpResponseException(json($result));
    }

    /**
     * 快捷查询逻辑器
     * @param string|\think\db\Query $dbQuery
     * @return Query
     */
    protected function _query($dbQuery) {
        return (new Query($dbQuery))->init($this);
    }

    //认证失败
    protected function _loginFail($msg, $data = []) {
        $result = ['code' => 401, 'info' => $msg, 'data' => $data];
        throw new HttpResponseException(json($result));
    }

    protected function _check_login($str) {
        if (empty($str)) return false;
        $req = (array)json_decode(base64_decode($str));

        if (empty($req) || empty($req['i']) || empty($req['t'])) return false;
        $id = $req['i'];
        $token = html_entity_decode($req['t']);

        $userInfo = MemberModel::where('id', $id)->find();
        if (empty($userInfo)) return false;
        $account = $userInfo->account;
        $uk = Cache::get(md5('meet_you' . $account));
        if (password_verify($uk[0] . $uk[1] . $account . $uk[2], $token)) {
            $this->_userInfo = [
                'account'   => $userInfo['account'],
                'id'        => $userInfo['id'],
                'avatar'    => $userInfo['avatar'],
                'nickname'  => $userInfo['nickname'],
                'phone'     => $userInfo['phone'],
                'parent_id' => $userInfo['parent_id'],
                'level'     => $userInfo['level'],
                'status'    => $userInfo['status']
            ];

            $this->_token = base64_encode(json_encode(['i' => $userInfo['id'], 't' => password_hash($uk[0] . $uk[1] . $account . $uk[2], PASSWORD_DEFAULT)]));
            return true;
        } else {
            return false;
        }
    }

    protected function _salt($length = 22) {
        return substr(sha1(date('r')), rand(0, 17), $length);
    }

}